package com.xiaokaceng.openci.application.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.lang3.StringUtils;
import org.dayatang.querychannel.QueryChannelService;
import org.openkoala.koala.auth.ss3adapter.AuthUserUtil;
import org.springframework.transaction.annotation.Transactional;

import com.xiaokaceng.openci.EntityNullException;
import com.xiaokaceng.openci.application.ProjectApplication;
import com.xiaokaceng.openci.domain.Project;
import com.xiaokaceng.openci.domain.ProjectDetail;
import com.xiaokaceng.openci.domain.ProjectStatus;
import com.xiaokaceng.openci.domain.Tool;
import com.xiaokaceng.openci.dto.ProjectDetailDto;
import com.xiaokaceng.openci.dto.ProjectDto;
import com.xiaokaceng.openci.dto.ProjectListDto;
import com.xiaokaceng.openci.executor.ProjectEmailSendExecutor;

@Named
@Transactional(value = "transactionManager_opencis")
public class ProjectApplicationImpl implements ProjectApplication {

	@Inject
	private QueryChannelService queryChannel;

	@Inject
	private ProjectEmailSendExecutor projectEmailSendExecutor;

	public boolean createProject(ProjectDto projectDto) {
		Project projectForCis = initProject(projectDto);
		projectForCis.setProjectStatus(ProjectStatus.INTEGRATION_TOOL);
		projectForCis.save();
		return true;
	}

	private Project initProject(ProjectDto projectDto) {
		Project projectForCis = projectDto.getProjectForCis();
		if (projectForCis == null) {
			throw new EntityNullException();
		}
		projectForCis.setProjectDetail(createProjectDetail(projectDto));
		return projectForCis;
	}

	private String getProjectSavePath() {
		return System.getProperty("java.io.tmpdir");
	}

	private ProjectDetail createProjectDetail(ProjectDto projectDto) {
		ProjectDetail projectDetail = new ProjectDetail();
		org.openkoala.koala.widget.Project project = projectDto.getProjectForCreate();
		projectDetail.setArtifactId(project.getArtifactId());
		projectDetail.setGroupId(project.getGroupId());
		projectDetail.setIntegrationCas(projectDto.isUserCas());
		settingProjectSavePath(projectDto, projectDetail);
		if (projectDto.getScmConfig() != null) {
			projectDetail.setScmRepositoryUrl(projectDto.getScmConfig().getRepositoryUrl());
			projectDetail.setScmType(projectDto.getScmConfig().getScmType());
		}
		return projectDetail;
	}

	private void settingProjectSavePath(ProjectDto projectDto, ProjectDetail projectDetail) {
		if (StringUtils.isNotBlank(projectDto.getImportProjectSavePath())) {
			projectDetail.setProjectSavePath(projectDto.getImportProjectSavePath());
		} else {
			projectDetail.setProjectSavePath(getProjectSavePath() + File.separator + projectDto.getProjectName());
		}
	}

	public void addIntegrationTool(Project project, Tool tool) {
		if (project == null) {
			throw new EntityNullException();
		}
		project.addTool(tool);
	}

	@SuppressWarnings("unchecked")
	public List<ProjectListDto> pagingQueryProject(int currentPage, int pagesize) {
		List<Object> conditionVals = new ArrayList<Object>();
		Date now = new Date();
		conditionVals.add(now);
		conditionVals.add(now);
		conditionVals.add(AuthUserUtil.getLoginUser().getUsername());
		
		StringBuilder jpql = new StringBuilder("select _project from Project _project where _project.createDate <= ? and _project.abolishDate > ? and _project.lead = ?");
		return ProjectListDto.transformBy(queryChannel.createJpqlQuery(jpql.toString()).setParameters(conditionVals).setPage(currentPage, pagesize).list());
	}

	public Project getDetail(long projectId) {
		return Project.get(Project.class, projectId);
	}
	
	public ProjectDetailDto getDetailToDto(long projectId) {
		return ProjectDetailDto.transformBy(Project.get(Project.class, projectId));
	}

	public boolean isExistByName(String name) {
		return Project.isExixtByName(name);
	}

	public void updateIntegrationToolStatus(long toolId) {
		Tool tool = Tool.get(Tool.class, toolId);
		tool.updateIntegrationStatus();
		updateProjectStatus(tool);
	}

	private void updateProjectStatus(Tool tool) {
		Project project = tool.getProject();
		project.updateProjectStatus();
		sendEmailToDeveloper(project);
	}

	private void sendEmailToDeveloper(Project project) {
		if (project.getProjectStatus().equals(ProjectStatus.SUCCESS)) {
			projectEmailSendExecutor.execute(project);
		}
	}

	public boolean remove(long projectId) {
		Project project = Project.get(Project.class, projectId);
		if (project == null) {
			return false;
		}
		project.abolish(new Date());
		return true;
	}

	public String integrationProcess(long projectId) {
		Project project = Project.get(Project.class, projectId);
		if (project == null) {
			throw new EntityNullException();
		}
		return project.integrationProcess();
	}

	public void againIntegration(long projectId) {
		Project project = Project.get(Project.class, projectId);
		if (project != null) {
			for (Tool tool : project.getTools()) {
				tool.againIntegrationTool();
			}
			project.updateProjectStatus();
		}
	}

}
